#ifndef __VSFJSON_H_INCLUDED__
#define __VSFJSON_H_INCLUDED__

enum vsfjson_type_t
{
	VSFJSON_TYPE_INVALID,
	VSFJSON_TYPE_OBJECT,
	VSFJSON_TYPE_ARRAY,
	VSFJSON_TYPE_STRING,
	VSFJSON_TYPE_NUMBER,
	VSFJSON_TYPE_BOOLEAN,
	VSFJSON_TYPE_NULL,
};

struct vsfjson_enumerator_t
{
	char *ptr;
	enum vsfjson_type_t type;
	bool first;
};

struct vsfjson_constructor_t
{
	union
	{
		void *param;
		uint32_t len;
	};
	int (*write_str)(void *, char *, int);

	bool first;
	bool result;
};

enum vsfjson_type_t vsfjson_enumerate_start(struct vsfjson_enumerator_t *e,
		const char *json);
char *vsfjson_enumerate_next(struct vsfjson_enumerator_t *e);
char *vsfjson_get(const char *json, const char *key);
int vsfjson_num_of_entry(const char *json);

enum vsfjson_type_t vsfjson_get_type(const char *json);
int vsfjson_get_string(const char *json, char *result, int len);
int vsfjson_get_number(const char *json, double *result);
int vsfjson_get_boolean(const char *json, bool *result);

void vsfjson_constructor_init(struct vsfjson_constructor_t *c, void *param,
		int (*write_str)(void *, char *, int));

int vsfjson_write_str(struct vsfjson_constructor_t *c, char *buf, int len);
int vsfjson_set_key(struct vsfjson_constructor_t *c, char *key);
#define vsfjson_set_object(c, key, member)	\
do {\
	int len = vsfjson_set_key((c), (key));\
	if (len < 0) break;\
	(c)->first = true;\
	len = vsfjson_write_str((c), "{", 1);\
	if (len < 0) break;\
	member\
	len = vsfjson_write_str((c), "}", 1);\
	if (len < 0) break;\
} while (0)


#define vsfjson_set_array(c, key, member)	\
do {\
	int len = vsfjson_set_key((c), (key));\
	if (len < 0) break;\
	(c)->first = true;\
	len = vsfjson_write_str((c), "[", 1);\
	if (len < 0) break;\
	member\
	len = vsfjson_write_str((c), "]", 1);\
	if (len < 0) break;\
} while (0)

int vsfjson_set_string(struct vsfjson_constructor_t *c, char *key, char *value);
int vsfjson_set_number(struct vsfjson_constructor_t *c, char *key, double value);
int vsfjson_set_boolean(struct vsfjson_constructor_t *c, char *key, bool value);
int vsfjson_set_null(struct vsfjson_constructor_t *c, char *key);

#endif	// __VSFJSON_H_INCLUDED__
